package com.icee.myth.utils;

/********************************************************************
 * Simple class that generates a java file containing a
 * build version sequence number.
 *
 * Version 1.0: By polugen@163.com
 * Build sequence numbers are of the form:
 *
 * <version>.<subversion>:<buildnumber>
 *
 * The class generated exposes the
 *
 *  getBuildVersion();         // the whole lot
 *  getBuildNumber();         // the build number
 *  getVersion();          // the build/product version
 *  getRevision();          // the build/product update/revision
 *  toString();              // the build/product update/revision
 *
 * The ant task works by keeping track of the buildnumber in a file
 * stored within the /var/ant directory and incrementing it after
 * creating the simple java class file.
 *
 *********************************************************************/
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

import java.util.*;
import java.io.*;

public class BuildVersion extends Task {

    private String version;
    private String revision;
    private long buildNumber = -1;
    private String baseDir;//"E:/Project_Myth/trunk/ProjectCServer/src";  // The root of the source tree
    private String projectName;
    private String packageName;

    /*********************************************************************
     * Creates the file
     **********************************************************************/
    @Override
    public void execute() throws BuildException {
        if (version == null) {
            throw new BuildException("Can't generate Version.java for lack of build param {version}");
        }

        if (revision == null) {
            throw new BuildException("Can't generate Version.java for lack of build param {revision}");
        }

        if (baseDir == null) {
            throw new BuildException("Can't generate Version.java for lack of build param {baseDir}");
        }

        if (projectName == null) {
            throw new BuildException("Can't generate Version.java for lack of build param {projectName}");
        }

        if (packageName == null) {
            throw new BuildException("Can't generate Version.java for lack of build param {packageName}");
        }

        buildNumber = getNextBuildNumber();
        PrintStream out = null;
        File versionFile = new File(baseDir +  "/src/" + packageName.replace('.', '/') + "/Version.java");
        System.out.println("    [build] creating : " + versionFile);
        try {
            out = new PrintStream(new FileOutputStream(versionFile));
            out.println("/***************************************************/");
            out.println("// Author:Panyg     AUTO GENERATED BY ANT ");
            out.println("// " + projectName + " Build = " + version + "." + revision + "." + buildNumber);
            //out.println("// File : " + getFilename());
            out.println();
            out.println("package " + packageName + ";");
            out.println();
            //out.println("import java.util.Date;");
            out.println();
            out.println("public class Version");
            out.println("{");
            out.println(" static  public String getBuildVersion() { return \"" + version + "." + revision + "." + buildNumber + "\"; }");
            out.println(" static  public String getBuildNumber() {return \"" + buildNumber + "\";}");
            out.println(" static  public String getVersion() {return \"" + version + "\";}");
            out.println(" static  public String getRevision() {return \"" + revision + "\";}");
            out.println(" static  public String getBuildDate() {return \"" + (new Date()).toString() + "\";}");
            out.println("}");
            out.println("/******************** END OF FILE ***************/");
            out.println();
        } catch (Exception ex) {
            throw new BuildException(ex.getMessage());
        } finally {
            if (out != null) {
                try {
                    out.close();
                    out = null;
                } catch (Exception ex1) {
                    throw new BuildException("Can't close file[Version.java]");
                }
            }
        }
    }

    /*********************************************************************
     * Sets the product version
     **********************************************************************/
    public void setVersion(String msg) {
        version = msg;
    }

    /*********************************************************************
     * Sets the product revision
     **********************************************************************/
    public void setReVision(String msg) {
        revision = msg;
    }

    /*********************************************************************
     * Sets the basedir of the source tree.
     **********************************************************************/
    public void setBaseDir(String dir) {
        baseDir = dir;
    }

    /*********************************************************************
     * Sets the package name
     **********************************************************************/
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    /*********************************************************************
     * Sets the project name of the source tree.
     **********************************************************************/
    public void setProductName(String name) {
        projectName = name;
    }

    /*********************************************************************
     * This function gets the next build sequence generating
     * storage in "/var/ant" as appropriate and overwriting it
     * afterwards.
     *
     * Returns -1 if cannot access file etc
     **********************************************************************/
    long getNextBuildNumber() {
        String fileName = baseDir + "/" + projectName + "_" + version + "_" + revision + ".txt";
        File theFile = new File(fileName);
        Properties prop = new Properties();
        long ver = -1;
        InputStream input = null;
        OutputStream output = null;

        try {
            // 1 - Read file
            //     System.out.println("\t\tReading Configuration in '"+theFile+"'");
            if (theFile.exists()) {
                input = new FileInputStream(theFile);
                prop.load(input);
                input.close();
                input = null;
            }
            if (prop.containsKey("buildnumber")) {
                ver = (new Integer((String) prop.get("buildnumber"))).longValue();
            } else {
                ver = 0;
            }
            // 2 - update and re-write
            prop.put("buildnumber", "" + (++ver));
            output = new FileOutputStream(theFile);
            prop.store(output, "Build Number System for " + projectName);
            output.close();
            output = null;
// System.out.println("Build number = "+ver);
        } catch (Exception ex) {
            ver = -1;
        } finally {
            try {
                if (input != null) {
                    input.close();
                }
                if (output != null) {
                    output.close();
                }
            } catch (Exception n) {
                throw new BuildException("Can't close " + fileName);
            }
        }
        return ver;
    }
}
